#include <assert.h>
#include <stdarg.h>
#include <iostream>

#include "sparrow/hash.h"
#include "sparrow/date.h"
#include "sparrow/hash.h"
#include "sparrow/format.h"

using namespace sparrow;
void test_str_split() {
    // auto r = StrSplit("- This, a sample string.", " ,.-");
    auto r = StrSplit("- This, a sample string.", [](char c) -> bool {
        if (c == ' ' || c == ',' || c == '.' || c == '-') {
            return true;
        }
        return false;
    });

    for (const auto &item : r) {
        std::cout << "[" << item << "]" << std::endl;
    }
}

void test_strip() {
    auto r = StripPrefix("HelloWorld", "Hello");
    std::cout << "StripPrefix:[" << r << "]" << std::endl;
    auto e = StripSuffix("HelloWorld", "World");
    std::cout << "StripSuffix:[" << e << "]" << std::endl;

    std::string s("   AbdcDEF ");
    std::string ss = StrTrim(s);
    std::cout << "StrTrim:[" << ss << "]" << std::endl;
    Trim(s);
    std::cout << "Trim:[" << s << "]" << std::endl;
    std::cout << "ToUpper:[" << ToUpper(ss) << "]" << std::endl;
    std::cout << "ToLower:[" << ToLower(ss) << "]" << std::endl;
}

void test_format() {
    auto s = "Austin";
    int age = 10;
    auto str = Printf("My name is %s, i am %d years old", s, age);
    std::cout << "Printf:[" << str << "]" << std::endl;

    std::string f = Format("{} world{} {}", "Hello", '!', 123);
    assert(f == "Hello world! 123");
    assert(Format("abc:{   {  !", "Hello", '!', 123) == "abc:{   {  !");
    assert(Format("abc:{   {}  !", "Hello", '!', 123) == "abc:{   Hello  !");

    std::cout << "format:[" << f << "]" << std::endl;
    std::string ip = "127.0.0.1";
    int port = 9527;
    std::cout << "Asprintf:" << Asprintf("address=>%s:%d", ip, port) << std::endl;
}

void test_date_time() {
    std::cout << DateTimeString() << std::endl;
    std::cout << FixTimestampString() << std::endl;
    std::cout << UTCTimeString() << std::endl;
    std::cout << DateTimeFriendlyString() << std::endl;
    std::cout << ShortDateString() << std::endl;
    std::cout << DateString() << std::endl;
    std::cout << TimeString24Hour() << std::endl;
    std::cout << TimeString12Hour() << std::endl;
}

void test_hex() {
    std::string input;
    input.resize(3);
    input[0] = 0x23;
    input[1] = 0x4e;
    input[2] = 0xAC;

    std::string output = hex(input);
    std::cout << "hex_encode:" << output << std::endl;
    assert(output == "234EAC");
    std::string res = unhex(output);
    std::cout << "hex_decode:" << Format("{}:{}:{}", (int)res[0], (int)res[1], (int)res[2])
              << std::endl;
    assert(input == res);
}
void test_str_cat() {
    std::string str = StrCat("Hello", 1, 2, 3, 'a', 13.14);
    assert(str == "Hello123a13.14");
    std::cout << "StrCat:" << str << std::endl;
}

int main() {
    test_str_split();
    test_strip();
    test_format();
    test_date_time();
    test_hex();
    test_str_cat();
    return 0;
}
